// 保存生成的图片信息
class Txt2ImgInfoHelper {
    // 解析参数
    static parseParameters() {
        return {
            // type: 'sub'|'save'|'new',
            /*
            * sub 在某个分类下创建新分类
            * save 直接保存到某个分类中
            * new 在根目录创建新分类
            * */
            // 保存的类型（新建子级并保存、保存）
            type: document.querySelector("#zj--dialog-input-type").value,
            // 保存的 JSON 路径
            path: JSON.parse(document.querySelector("#zj--dialog-input-path").value ? document.querySelector("#zj--dialog-input-path").value : "{}"),
            // 如果类型为新建子级并保存，则子级名
            subName: document.querySelector("#zj--dialog-input-sub-name").value,
            // 标签名
            tagName: document.querySelector("#zj--dialog-input-tag-name").value,
            // 正向提示词
            positivePrompt: document.querySelector(ElementSelector.sys_txt2img_prompt_positive_selector).value || '',
            // 负向提示词
            negativePrompt: document.querySelector(ElementSelector.sys_txt2img_prompt_negative_selector).value || '',
            // 迭代步数
            parameters: {
                steps: document.querySelector(ElementSelector.sys_txt2img_steps_parameter_selector).value || '',
                // 采样方法
                sampler: document.querySelector(ElementSelector.sys_txt2img_sampler_parameter_selector).value || '',
                // 提示词引导系数
                CFGScale: document.querySelector(ElementSelector.sys_txt2img_cfg_scale_parameter_selector).value || '',
                // 随机数种子
                seed: document.querySelector(ElementSelector.sys_txt2img_seed_parameter_selector).value || '',
                // 尺寸
                size: {
                    width: document.querySelector(ElementSelector.sys_txt2img_width_parameter_selector).value || '',
                    height: document.querySelector(ElementSelector.sys_txt2img_height_parameter_selector).value || ''
                },
                model: document.querySelector(ElementSelector.sys_txt2img_model_parameter_selector).value || '', // 模型
                modelHash: document.querySelector("#sd_checkpoint_hash").textContent,// 模型哈希
                version: document.querySelector(ElementSelector.sys_txt2img_version_parameter_selector).textContent
            }
        }
    }

    static resetInputValue() {
        document.querySelector("#zj--dialog-input-type").value = '';
        document.querySelector("#zj--dialog-input-path");
        document.querySelector("#zj--dialog-input-sub-name").value = '';
        document.querySelector("#zj--dialog-input-tag-name").value = '';
    }

    // 打开或关闭菜单
    static closeOrOpenMenu(subNode, alwaysClose = false) {
        // 判断是否有子菜单
        if (subNode.querySelector("ul")) {
            if (alwaysClose) {
                subNode.querySelector("ul").style.display = 'none';
            } else {
                if (subNode.querySelector("ul").style.display === 'none') {
                    subNode.querySelector("ul").style.display = 'flex';
                } else {
                    subNode.querySelector("ul").style.display = 'none';
                }
            }
            // 关闭当前节点的所有子节点
            subNode.querySelector("ul").querySelectorAll("ul").forEach(i => {
                i.style.display = 'none';
            })
        }
        // 获取根元素
        const rootMenu = document.querySelector("#zj--dialog-container>ul");
        // 获取所有项
        const rootMenuItems = rootMenu.querySelectorAll("li");
        rootMenuItems.forEach(item => {
            // 判断点击的元素是不是当前项的，关闭当前节点以外其他项的所有菜单
            if (!item.contains(subNode)) {
                item.querySelectorAll("ul").forEach(i => {
                    i.style.display = 'none';
                })
            }
        })
    }

    // 渲染菜单
    static renderMenu(data) {
        const menu = document.createElement("ul");
        data.forEach(key => {
            if (key.subData && Array.isArray(key.subData)) {
                const li = document.createElement("li");

                const itemLabel = document.createElement('div');
                itemLabel.classList.add('zj--menu-item-label');
                // 创建每一个子项标题
                const itemTitle = document.createElement('span');
                itemTitle.classList.add('zj--menu-item-title');
                itemTitle.textContent = key.name;
                itemTitle.addEventListener('click', e => {
                    // 阻止冒泡
                    e.stopPropagation();
                    this.closeOrOpenMenu(li);
                    this.resetInputValue();

                    // 每次点击打开或关闭菜单时隐藏输入框
                    // 获取用于输入子级名的输入框
                    document.querySelector("#zj--dialog-input-sub-name-label").style.display = 'none';
                    // 获取用于输入标签名的输入框
                    document.querySelector("#zj--dialog-input-tag-name-label").style.display = 'none';
                })
                itemLabel.appendChild(itemTitle);

                li.appendChild(itemLabel);

                const subMenu = this.renderMenu(key.subData);

                // 判断子项有没有内容（即判断子项是否为最后一级）
                if (subMenu.children.length !== 0) {
                    subMenu.style.display = 'none';
                    li.appendChild(subMenu);
                }
                menu.appendChild(li)
            }
        })
        return menu;
    }

    // 创建预输入框
    static createInput() {
        // 操作类型
        const typeInput = document.createElement("input");
        typeInput.id = "zj--dialog-input-type";
        typeInput.style.display = 'none';

        // JSON 中的路径
        const pathInput = document.createElement("textarea");
        pathInput.id = "zj--dialog-input-path";
        pathInput.style.display = 'none';

        // 创建两个隐藏的输入框用于保存输入的标签名或子级名
        const label1 = document.createElement("label");
        label1.id = "zj--dialog-input-sub-name-label";
        label1.innerHTML = `<span>子级名：</span>`;
        const inputSubName = document.createElement("input");
        inputSubName.id = "zj--dialog-input-sub-name";
        label1.appendChild(inputSubName);
        label1.style.display = 'none';

        const label2 = document.createElement("label");
        label2.id = "zj--dialog-input-tag-name-label";
        label2.innerHTML = `<span>标签名：</span>`
        const inputTagName = document.createElement("input");
        inputTagName.id = "zj--dialog-input-tag-name";
        label2.appendChild(inputTagName);
        label2.style.display = 'none';

        document.body.appendChild(typeInput);
        document.body.appendChild(pathInput);
        document.body.appendChild(label1);
        document.body.appendChild(label2);
    }

    // 创建一个方法，用于在dom中删除并返回 元素;
    static peelElement(selector) {
        const element = document.querySelector(selector);
        element.remove();
        return element;
    }

    // 获取点击的路径
    static parsePath(li) {
        const path = {
            pathArr: [],
            indexArr: []
        }
        const currentTagName = li.firstElementChild.firstElementChild.textContent;
        const currentTagIndex = Array.prototype.indexOf.call(li.parentElement.children, li);
        path.pathArr.unshift(currentTagName);
        path.indexArr.unshift(currentTagIndex);
        if (li.parentElement.id !== 'zj--dialog-menu-root') {
            const newPath = this.parsePath(li.parentElement.parentElement);
            path.pathArr.unshift(...newPath.pathArr);
            path.indexArr.unshift(...newPath.indexArr)
        }
        return path;
    }

    // 渲染对话框
    static async renderDialog() {
        this.createInput();

        // 创建对话框
        const dialog = document.createElement("dialog");
        // 点击遮罩层关闭对话框
        dialog.addEventListener('click', (e) => {
            const rect = e.target.getBoundingClientRect();
            // 判断点击位置
            if (!(e.clientX >= rect.left && e.clientX <= rect.right && e.clientY >= rect.top && e.clientY <= rect.bottom)) {
                dialog.close();
                this.resetInputValue();
                PublicUtils.enableScroll();
            }
        });
        dialog.id = "zj--dialog";

        const dialogContainer = document.createElement("div");
        dialogContainer.id = "zj--dialog-container";


        const dialogOp = document.createElement("div");
        dialogOp.id = "zj--dialog-op";
        const closeDialogButton = ElementCreator.createButton("取消", {
            onClick: (e) => {
                dialog.close();
                this.resetInputValue();
                PublicUtils.enableScroll();
            }
        })
        closeDialogButton.id = "zj--dialog-close";

        // 保存按钮
        const saveButton = ElementCreator.createButton("保存", {
            onClick: (e) => {
                e.stopPropagation();
                const param = this.parseParameters();
                if (!param.type) {
                    alert("请选择保存位置！");
                } else if (param.type === 'sub' && (!param.tagName || !param.subName)) {
                    alert("请填写标签名或子级名");
                } else if (param.type === 'save' && !param.tagName) {
                    alert("请填写标签名");
                } else if (!param.positivePrompt && !param.negativePrompt) {
                    alert("当前没有提示词！")
                } else {
                    // 发送请求
                    fetch('http://localhost:7861/zj-api/add-prompt', {
                        method: 'POST', headers: {
                            'Content-Type': 'application/json'
                        },
                        body: JSON.stringify(this.parseParameters())
                    })
                        .then(response => response.json())
                        .then(data => {
                            console.log("保存成功", data);
                            const dialog = document.querySelector("#zj--dialog");
                            dialog.close();
                            PublicUtils.enableScroll();

                            this.resetInputValue();
                            PublicUtils.customDialog("保存成功！")
                        })
                        .catch(error => {
                            console.error("Error", error)
                        })
                }
            }
        })

        dialogOp.appendChild(closeDialogButton);
        dialogOp.appendChild(saveButton);
        dialogContainer.appendChild(dialogOp);
        // 获取数据
        const data = JSON.parse(localStorage.getItem("zjPrompt"));
        // 渲染菜单
        const menu = this.renderMenu(data);
        menu.id = 'zj--dialog-menu-root';

        dialogContainer.insertAdjacentElement('afterbegin', menu);
        dialog.appendChild(dialogContainer)
        document.body.appendChild(dialog);

        // 条件渲染作为补充
        this.renderByConditional();
    }

    // 条件渲染
    static renderByConditional() {
        const dialogContainer = document.querySelector("#zj--dialog-container");

        dialogContainer.querySelectorAll("li").forEach(l => {
            // 判断是否有下级菜单，并添加 zj-has-child 类名
            if (l.querySelector("ul")) {
                l.querySelector(".zj--menu-item-label>.zj--menu-item-title").classList.add('zj--has-child');
            }

            // 创建每一项 保存到此项 按钮
            const saveToHere = ElementCreator.createButton("保存到此项", {
                onClick: e => {
                    e.stopPropagation();
                    this.closeOrOpenMenu(l, true);
                    this.resetInputValue();

                    // 给输入框赋值
                    document.querySelector("#zj--dialog-input-type").value = 'save';
                    document.querySelector("#zj--dialog-input-path").value = JSON.stringify(this.parsePath(l));

                    // 获取用于输入子级名的输入框
                    const inputSubNameLabel = this.peelElement("#zj--dialog-input-sub-name-label");
                    inputSubNameLabel.style.display = 'none';
                    // 获取用于输入标签名的输入框
                    const inputTagNameLabel = this.peelElement("#zj--dialog-input-tag-name-label");

                    l.appendChild(inputSubNameLabel);
                    l.appendChild(inputTagNameLabel);

                    inputTagNameLabel.style.display = "flex";
                }, color: 'secondary'
            });
            saveToHere.classList.add('zj--menu-item-save-button')
            l.querySelector(".zj--menu-item-label").appendChild(saveToHere);

            // 新建 子级菜单 都需要
            // 创建每一项点击 新建子级 按钮
            const createNewChild = ElementCreator.createButton("新建子级", {
                onClick: e => {
                    e.stopPropagation();
                    this.closeOrOpenMenu(l, true);
                    this.resetInputValue();

                    // 给输入框赋值
                    document.querySelector("#zj--dialog-input-type").value = 'sub';
                    document.querySelector("#zj--dialog-input-path").value = JSON.stringify(this.parsePath(l));

                    // 获取用于输入子级名的输入框
                    const inputSubNameLabel = this.peelElement("#zj--dialog-input-sub-name-label");
                    // 获取用于输入标签名的输入框
                    const inputTagNameLabel = this.peelElement("#zj--dialog-input-tag-name-label");
                    l.appendChild(inputSubNameLabel);
                    l.appendChild(inputTagNameLabel);

                    inputTagNameLabel.style.display = "flex";
                    inputSubNameLabel.style.display = 'flex';
                }, color: 'secondary'
            });
            createNewChild.classList.add('zj--menu-item-create-button')
            l.querySelector(".zj--menu-item-label").appendChild(createNewChild);
        })
    }

    // 创建保存生成的图片信息按钮
    static createSaveOrCopyButton() {
        const txt2imgResults = document.querySelector(ElementSelector.sys_txt2img_results_selector);
        const container = document.createElement("div");
        container.classList.add("zj--img-info-button");


        // 创建复制参数按钮 JSON
        const copyParametersButtonJSON = ElementCreator.createButton("复制参数为 JSON", {
            onClick: async (e) => {
                e.preventDefault();
                e.stopPropagation();
                const parameters = this.parseParameters();
                delete parameters.path
                delete parameters.type
                delete parameters.tagName
                delete parameters.subName

                // 写入剪贴板
                await navigator.clipboard.writeText(JSON.stringify(parameters));
                PublicUtils.customDialog("JSON 信息已保存到剪贴板");
            }, size: 'lg', color: 'secondary'
        })

        // 创建复制参数按钮 TXT
        const copyParametersButtonTXT = ElementCreator.createButton("复制参数为 TXT", {
            onClick: async (e) => {
                e.preventDefault();
                e.stopPropagation();
                // 写入剪贴板
                const text = `PositivePrompt: ${this.parseParameters().positivePrompt}
NegativePrompt: ${this.parseParameters().negativePrompt}
Steps: ${this.parseParameters().parameters.steps}
Sampler: ${this.parseParameters().parameters.sampler}
CFGScale: ${this.parseParameters().parameters.CFGScale}
Seed: ${this.parseParameters().parameters.seed}
Size: ${this.parseParameters().parameters.size.width} x ${this.parseParameters().parameters.size.height}
Model: ${this.parseParameters().parameters.model}
ModelHash: ${this.parseParameters().parameters.modelHash}
Version: ${this.parseParameters().parameters.version}`
                await navigator.clipboard.writeText(text);
                PublicUtils.customDialog("TXT 信息已保存到剪贴板");
            }, size: 'lg', color: 'secondary'
        })

        // 创建保存参数到快速提示词按钮
        const saveParametersButton = ElementCreator.createButton("保存当前参数到快速提示词", {
            onClick: e => {
                const dialog = document.querySelector("#zj--dialog");
                dialog.showModal();
                PublicUtils.disableScroll();
            }, size: 'lg', color: 'secondary'
        })

        container.appendChild(copyParametersButtonJSON);
        container.appendChild(copyParametersButtonTXT);
        container.appendChild(saveParametersButton);
        txt2imgResults.appendChild(container);
    }

    static execute() {
        this.renderDialog().then(r => console.log("菜单渲染完毕"));
        this.createSaveOrCopyButton();
    }
}